package com.example.carrierapp.ui.dialog;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.annotation.StyleRes;
import android.support.v4.app.ActivityCompat;
import android.support.v4.widget.TextViewCompat;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewStub;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.example.lb.fingerdemo.R;

import java.lang.ref.WeakReference;

/**
 * 对话框
 */
public class MAlertDialog extends Dialog {
    TextView mButtonPositive;
    private CharSequence mButtonPositiveText;
    Message mButtonPositiveMessage;
    private int mButtonPositiveColor;

    TextView mButtonNegative;
    private CharSequence mButtonNegativeText;
    Message mButtonNegativeMessage;
    private int mButtonNegativeColor;

    private TextView mTitleView;
    private TextView mMessageView;
    private CharSequence mMessage;
    private CharSequence mTitle;
    private View mView;
    private Drawable mTitleBackground;
    private int mTitleTextAppearance;

    private ButtonHandler mHandler;
    public MAlertDialog(@NonNull Context context) {
        super(context, R.style.AppTheme_Dialog);
        mHandler = new ButtonHandler(this);
    }

    MAlertDialog(Builder builder) {
        this(builder.mContext);
        setButton(DialogInterface.BUTTON_POSITIVE, builder.mPositiveButtonText, builder.mPositiveButtonListener);
        setButton(DialogInterface.BUTTON_NEGATIVE, builder.mNegativeButtonText, builder.mNegativeButtonListener);
        mMessage = builder.mMessage;
        mTitle = builder.mTitle;
        mView = builder.mView;
        mTitleBackground = builder.mTitleBackground;
        this.mTitleTextAppearance = builder.mTitleTextAppearance;
        mButtonPositiveColor = builder.mPositiveTextColor;
        mButtonNegativeColor = builder.mNagativeTextColor;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        installContent();
    }

    private void installContent() {
        setContentView(R.layout.dialog_layout_alert);
        setupViews();
    }

    private void setupViews() {
        int whichButtons = 0;
        final View line1 = findViewById(R.id.line1);
        final View line2 = findViewById(R.id.line2);
        mButtonPositive = findViewById(R.id.button_positive);
        mButtonNegative = findViewById(R.id.button_nagative);
        mButtonPositive.setOnClickListener(mButtonHandler);
        mButtonNegative.setOnClickListener(mButtonHandler);
        if (TextUtils.isEmpty(mButtonPositiveText)) {
            mButtonPositive.setVisibility(View.GONE);
        } else {
            mButtonPositive.setText(mButtonPositiveText);
            mButtonPositive.setVisibility(View.VISIBLE);
            whichButtons = whichButtons | 1;
        }
        if (mButtonPositiveColor != 0) {
            mButtonPositive.setTextColor(mButtonPositiveColor);
        }
        if (TextUtils.isEmpty(mButtonNegativeText)) {
            mButtonNegative.setVisibility(View.GONE);
            line2.setVisibility(View.GONE);
        } else {
            mButtonNegative.setText(mButtonNegativeText);
            mButtonNegative.setVisibility(View.VISIBLE);
            whichButtons = whichButtons | 2;
        }
        if (mButtonNegativeColor != 0) {
            mButtonNegative.setTextColor(mButtonNegativeColor);
        }
        final boolean hasButtons = whichButtons != 0;
        if (!hasButtons) {
            line1.setVisibility(View.GONE);
        }
        mMessageView = findViewById(R.id.message);
        if (mView != null) {
            ViewStub stub = findViewById(R.id.view_stub);
            FrameLayout fl = (FrameLayout) stub.inflate();
            fl.addView(mView);
            mMessageView.setVisibility(View.GONE);
        } else {
            if (mMessage != null) {
                mMessageView.setText(mMessage);
            } else {
                mMessageView.setVisibility(View.GONE);
            }
        }
        mTitleView = findViewById(android.R.id.title);
        if (mTitle != null) {
            mTitleView.setText(mTitle);
        } else {
            mTitleView.setVisibility(View.GONE);
        }
        if (mTitleBackground != null) {
            mTitleView.setBackground(mTitleBackground);
        }
        if (mTitleTextAppearance > 0) {
            TextViewCompat.setTextAppearance(mTitleView, mTitleTextAppearance);
        }
    }

    void setButtonTextColor(int whichButton, @ColorRes int colorRes) {
        switch (whichButton) {

            case DialogInterface.BUTTON_POSITIVE:
                mButtonNegativeColor = ActivityCompat.getColor(getContext(), colorRes);
                break;

            case DialogInterface.BUTTON_NEGATIVE:
                mButtonPositiveColor = ActivityCompat.getColor(getContext(), colorRes);
                break;

            default:
                throw new IllegalArgumentException("Button does not exist");
        }
    }

    /**
     * Sets a click listener or a message to be sent when the button is clicked.
     * You only need to pass one of {@code listener} or {@code msg}.
     *
     * @param whichButton Which button, can be one of
     *                    {@link DialogInterface#BUTTON_POSITIVE},
     *                    {@link DialogInterface#BUTTON_NEGATIVE}
     * @param text        The text to display in positive button.
     * @param listener    The {@link OnClickListener} to use.
     */
    public void setButton(int whichButton, CharSequence text, OnClickListener listener) {
        Message msg = null;
        if (listener != null) {
            msg = mHandler.obtainMessage(whichButton, listener);
        }

        switch (whichButton) {

            case DialogInterface.BUTTON_POSITIVE:
                mButtonPositiveText = text;
                mButtonPositiveMessage = msg;
                break;

            case DialogInterface.BUTTON_NEGATIVE:
                mButtonNegativeText = text;
                mButtonNegativeMessage = msg;
                break;

            default:
                throw new IllegalArgumentException("Button does not exist");
        }
    }

    public void setTitle(@StringRes int resId) {
        super.setTitle(resId);
        mTitle = getContext().getString(resId);
        if (mTitleView != null) {
            mTitleView.setText(mTitle);
        }
    }

    public void setTitleStyle(@StyleRes int resId) {
        if (mTitleView != null) {
            TextViewCompat.setTextAppearance(mTitleView, resId);
        }
    }

    public void setMessage(CharSequence message) {
        mMessage = message;
        if (mMessageView != null) {
            mMessageView.setText(mMessage);
        }
    }

    public void setMessage(@StringRes int resId) {
        setMessage(getContext().getString(resId));
    }

    private final View.OnClickListener mButtonHandler = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final Message m;
            if (v == mButtonPositive && mButtonPositiveMessage != null) {
                m = Message.obtain(mButtonPositiveMessage);
            } else if (v == mButtonNegative && mButtonNegativeMessage != null) {
                m = Message.obtain(mButtonNegativeMessage);
            } else {
                m = null;
            }

            if (m != null) {
                m.sendToTarget();
            }

            // Post a message so we dismiss after the above handlers are executed
            mHandler.obtainMessage(ButtonHandler.MSG_DISMISS_DIALOG, MAlertDialog.this)
                    .sendToTarget();
        }
    };

    private static final class ButtonHandler extends Handler {
        // Button clicks have Message.what as the BUTTON{1,2,3} constant
        private static final int MSG_DISMISS_DIALOG = 1;

        private WeakReference<DialogInterface> mDialog;

        public ButtonHandler(DialogInterface dialog) {
            mDialog = new WeakReference<>(dialog);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {

                case DialogInterface.BUTTON_POSITIVE:
                case DialogInterface.BUTTON_NEGATIVE:
                case DialogInterface.BUTTON_NEUTRAL:
                    ((OnClickListener) msg.obj).onClick(mDialog.get(), msg.what);
                    break;

                case MSG_DISMISS_DIALOG:
                    ((DialogInterface) msg.obj).dismiss();
            }
        }
    }

    public static class Builder {
        Context mContext;
        CharSequence mTitle;
        CharSequence mMessage;

        CharSequence mPositiveButtonText;
        OnClickListener mPositiveButtonListener;

        CharSequence mNegativeButtonText;
        OnClickListener mNegativeButtonListener;

        boolean mCancelable = true;

        OnCancelListener mOnCancelListener;
        OnDismissListener mOnDismissListener;
        OnKeyListener mOnKeyListener;

        int mPositiveTextColor;
        int mNagativeTextColor;

        View mView;

        Drawable mTitleBackground;

        int mTitleTextAppearance;

        public Builder(Context context) {
            this.mContext = context;
        }

        public Builder setTitle(CharSequence title) {
            mTitle = title;
            return this;
        }

        public Builder setTitle(@StringRes int resId) {
            mTitle = mContext.getString(resId);
            return this;
        }

        public Builder setMessage(CharSequence message) {
            mMessage = message;
            return this;
        }

        public Builder setMessage(@StringRes int resId) {
            return setMessage(mContext.getString(resId));
        }

        public Builder setPositiveButton(CharSequence positiveButtonText, OnClickListener clickListener) {
            mPositiveButtonText = positiveButtonText;
            mPositiveButtonListener = clickListener;
            return this;
        }

        public Builder setPositiveButton(@StringRes int resId, OnClickListener clickListener) {
            mPositiveButtonText = mContext.getString(resId);
            mPositiveButtonListener = clickListener;
            return this;
        }

        public Builder setNegativeButton(CharSequence negativeButtonText, OnClickListener clickListener) {
            mNegativeButtonText = negativeButtonText;
            mNegativeButtonListener = clickListener;
            return this;
        }

        public Builder setNegativeButton(@StringRes int resId, OnClickListener clickListener) {
            mNegativeButtonText = mContext.getString(resId);
            mNegativeButtonListener = clickListener;
            return this;
        }

        public Builder setCancelable(boolean cancelable) {
            mCancelable = cancelable;
            return this;
        }

        public Builder setOnCancelListener(OnCancelListener onCancelListener) {
            mOnCancelListener = onCancelListener;
            return this;
        }

        public Builder setOnDismissListener(OnDismissListener onDismissListener) {
            mOnDismissListener = onDismissListener;
            return this;
        }

        public Builder setOnKeyListener(OnKeyListener onKeyListener) {
            mOnKeyListener = onKeyListener;
            return this;
        }

        public Builder setPositiveTextColor(@ColorRes int positiveTextColor) {
            mPositiveTextColor = ActivityCompat.getColor(mContext, positiveTextColor);
            return this;
        }

        public Builder setNagativeTextColor(@ColorRes int nagativeTextColor) {
            mNagativeTextColor = ActivityCompat.getColor(mContext, nagativeTextColor);
            return this;
        }

        public Builder setView(View view) {
            this.mView = view;
            return this;
        }

        public Builder setTitleBackground(Drawable drawable) {
            this.mTitleBackground = drawable;
            return this;
        }

        public Builder setTitleTextAppearance(@StyleRes int appearance) {
            mTitleTextAppearance = appearance;
            return this;
        }

        public Builder setWhiteTitleText() {
            mTitleTextAppearance = R.style.livelyDialogTitleText;
            return this;
        }

        public MAlertDialog create() {
            MAlertDialog dialog = new MAlertDialog(this);
            dialog.setCancelable(mCancelable);
            dialog.setOnCancelListener(mOnCancelListener);
            dialog.setOnDismissListener(mOnDismissListener);
            if (mOnKeyListener != null) {
                dialog.setOnKeyListener(mOnKeyListener);
            }
            return dialog;
        }

        public MAlertDialog show() {
            final MAlertDialog dialog= create();
            dialog.show();
            return dialog;
        }
    }
}
